package com.hmdp.config;

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.datatype.jsr310.*;
import org.springframework.context.annotation.*;
import org.springframework.data.redis.cache.*;
import org.springframework.data.redis.connection.*;
import org.springframework.data.redis.serializer.*;

import java.time.*;
import java.util.*;

import static com.hmdp.utils.RedisConstants.CACHE_SHOP_KEY;

@Configuration
public class CacheConfig {

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        // 创建ObjectMapper用于处理序列化和反序列化
        ObjectMapper objectMapper = new ObjectMapper();
        // 注册JavaTimeModule以支持Java 8日期时间类型
        objectMapper.registerModule(new JavaTimeModule());
        // 禁用将日期序列化为时间戳格式，保持可读性
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        // 启用默认的多态类型信息处理，以便在反序列化时保留类型信息
        objectMapper.activateDefaultTyping(
                objectMapper.getPolymorphicTypeValidator(),
                ObjectMapper.DefaultTyping.NON_FINAL,
                JsonTypeInfo.As.PROPERTY
        );
        // 创建通用的Jackson2 JSON Redis序列化器
        GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(objectMapper);
        // 定义默认的缓存配置，设置缓存条目过期时间为10分钟，并使用定义好的序列化器
        RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(10))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer));
        // 创建缓存配置映射，允许为不同的缓存名称定义不同的配置
        Map<String, RedisCacheConfiguration> cacheConfigurations = new HashMap<>();
        // 为店铺缓存设置单独的过期时间（1小时）
        cacheConfigurations.put(CACHE_SHOP_KEY+"::list", defaultConfig.entryTtl(Duration.ofHours(1)));
        // 构建RedisCacheManager实例，使用默认配置和自定义的缓存配置初始化
        return RedisCacheManager.builder(connectionFactory)
                .cacheDefaults(defaultConfig)
                .withInitialCacheConfigurations(cacheConfigurations)
                .build();
    }
}